package com.duniptech.soa.simulation;

import java.io.StringReader;

import javax.xml.bind.JAXB;

import org.w3c.dom.Element;

import com.duniptech.soa.modeling.AtomicDevsJava;
import com.duniptech.soa.modeling.AtomicInterface;
import com.duniptech.soa.modeling.AtomicMicroSim;
import com.duniptech.soa.modeling.Port;
import com.duniptech.soa.modeling.Ports;
import com.duniptech.soa.util.Util;

/**
 * @author  jlrisco
 */
public class Simulator {	

	//private String name;
	protected AtomicInterface model;
	protected double tL;
	protected double tN;
	
	public Simulator(Element xmlComponent) throws Exception {
		//this.name = xmlAtomic.getAttribute("name");
		if(Util.debug) System.out.println("Simulator::Simulator BEGIN");
		String platform = xmlComponent.getAttribute("platform");
		if(platform.equals("MicroSim"))
			model = new AtomicMicroSim(xmlComponent);
		else if(platform.equals("devsjava"))
			model = new AtomicDevsJava(xmlComponent);
		if(Util.debug) System.out.println("Simulator::Simulator END");
	}
	
	public void initialize(double t) {
		model.initialize();
		tL = t;
		tN = t + model.ta();
	}
	
	/**
	 * @return  the tN
	 */
	public double getTN() {
		return tN;
	}
	
	public void lambda(double t) {
		model.getOutput().clear();
		if(t==tN) 
			model.lambda();
	}
	
	public void deltfcn(double t) {
		Ports input = model.getInput();
		if(input==null) {
			System.out.println("ERROR RECEIVED NULL INPUT " + model.toString());
			return;
		}
		if (input.isEmpty() && t!=tN) {
			return;
		}
		else if((!input.isEmpty()) && t==tN) {
			double e = t - tL;
			model.deltcon(e);
		}
		else if(t==tN) {
			model.deltint();
		}
		else if(!input.isEmpty()) {
			double e = t - tL;
			model.deltext(e);
		}
		tL = t;
		tN = tL + model.ta();	
		input.clear();	
	}
	
	public String[] getOutput(String portName) {
		return model.getOutput(portName);
	}
	
	public void receive(String simulatorFrom, String portFrom, String simulatorTo, String portTo, String[] xmlValues) throws Exception {
		if(Util.debug) System.out.println(simulatorFrom + "(" + portFrom + ")-->"+simulatorTo + "(" + portTo + "):");
		for(int i=0; i<xmlValues.length; i++) {
			if(Util.debug) System.out.println("Value " + i + "\n" + xmlValues[i]);
			Port port = model.getInput().get(portTo);
			StringReader reader = new StringReader(xmlValues[i]);
			Object value = JAXB.unmarshal(reader, Class.forName(port.getPortClass()));
			model.getInput().get(portTo).addValue(value);

		}
	}
	
}
